package com.xinou.daily_report.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinou.common.base.config.ApiResponse;
import com.xinou.common.base.exception.BusException;
import com.xinou.common.enumerate.HttpStatusEnum;
import com.xinou.common.util.BeanUtil;
import com.xinou.daily_report.PO.WeekPlanPO;
import com.xinou.daily_report.PO.WeekPlanUpdateSinglePO;
import com.xinou.daily_report.PO.WeekPlanUpdatePO;
import com.xinou.daily_report.PO.WeekPlanPO;
import com.xinou.daily_report.VO.WeekPlanInfoVO;
import com.xinou.daily_report.entity.*;
import com.xinou.daily_report.entity.SysWeekPlan;
import com.xinou.daily_report.mapper.SysWeekPlanMapper;
import com.xinou.daily_report.service.SysWeekPlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinou.daily_report.service.SysWeekTimeService;
import com.xinou.sso.service.SysUserService;
import com.xinou.sso.util.ShiroUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2021-06-11
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysWeekPlanServiceImpl extends ServiceImpl<SysWeekPlanMapper, SysWeekPlan> implements SysWeekPlanService {
    private final SysWeekTimeService sysWeekTimeService;

    private final SysUserService sysUserService;
    private final SysWeekPlanMapper sysWeekPlanMapper;



    @Override
    public ApiResponse<WeekPlanInfoVO> weekPlanList(WeekPlanPO po) {
        LocalDateTime now = LocalDateTime.now();
        po.setSelectTime(now.plusWeeks(1L));
        Page<WeekPlanPO> page = new Page<>(po.getPageNumber(), po.getPageSize());
        Page<WeekPlanInfoVO> weekPlanInfoVOPage = sysWeekPlanMapper.weekPlanMapperList(page,po);
        return new ApiResponse<>(weekPlanInfoVOPage.getRecords(),weekPlanInfoVOPage.getTotal());
    }


    @Override
    public ApiResponse<Void> weekPlanSave (WeekPlanUpdatePO weekPlanUpdatePO){
        //先找到本周的weekId
        LocalDateTime now = LocalDateTime.now().plusWeeks(1L);
//        if (now.getDayOfWeek().getValue()>1) {
//            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周计划提交时间截止已过");
//        }
        Long weekTimeId;
        SysWeekTime sysWeekTimeServiceOne = sysWeekTimeService.getOne(new LambdaQueryWrapper<SysWeekTime>()
                .le( SysWeekTime::getBeginTime, now)
                .ge( SysWeekTime::getEndTime, now));
        if (sysWeekTimeServiceOne==null){
            //添加之前先判断当前时间是否存在不在的话向时间表里插入一个数据
            Date from = Date.from(Instant.now());
            DateTime begin = DateUtil.beginOfWeek(from);
            DateTime end = DateUtil.endOfWeek(from);
            Instant beginInstant = begin.toInstant();
            ZoneId beginZoneId = ZoneId.systemDefault();
            Instant endInstant = end.toInstant();
            ZoneId endZoneId = ZoneId.systemDefault();
            LocalDateTime beginLocalDateTime = LocalDateTime.ofInstant(beginInstant, beginZoneId);
            LocalDateTime endLocalDateTime = LocalDateTime.ofInstant(endInstant, endZoneId);
            //这周设置下周的时间
//            LocalDateTime begin1 = beginLocalDateTime.plusWeeks(1L);
//            LocalDateTime end1 = endLocalDateTime.plusWeeks(1L);
            SysWeekTime sysWeekTime = new SysWeekTime();
            sysWeekTime.setBeginTime(beginLocalDateTime.plusWeeks(1L));
            LocalDateTime time = endLocalDateTime.plusDays(6L).plusHours(23).plusMinutes(59).plusSeconds(59);
            sysWeekTime.setEndTime(time);
//            sysWeekTime.setEndTime(endLocalDateTime.plusWeeks(1L));
            sysWeekTimeService.save(sysWeekTime);
            sysWeekTimeServiceOne = sysWeekTimeService.getOne(new LambdaQueryWrapper<SysWeekTime>()
                    .le( SysWeekTime::getBeginTime, now)
                    .ge( SysWeekTime::getEndTime, now));
        }
        weekTimeId=sysWeekTimeServiceOne.getId();

        if(count(new LambdaQueryWrapper<SysWeekPlan>()
                .eq(SysWeekPlan::getWeekId,sysWeekTimeServiceOne.getId())
                .eq(SysWeekPlan::getUserId,ShiroUtil.getUserId())
        )>0){
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "您本周已经添加过了，请勿重复添加");
        }


        List<WeekPlanUpdateSinglePO> weekPlanPOList = weekPlanUpdatePO.getWeekPlanPOList();
        if (weekPlanPOList.isEmpty()) {
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周计划不能为空");
        }
        if (weekPlanPOList.size() > 20) {
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周计划长度最大为20");
        }
        for (WeekPlanUpdateSinglePO weekPlanPO : weekPlanPOList) {
            if (weekPlanPO.getWeekDay() == null) {
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "所有周计划的时间都不能为空");
            }
            if(weekPlanPO.getTaskDifficulty()==null){
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "所有周计划的任务难度都不能为空");
            }
            weekPlanPO.setUserId(ShiroUtil.getUserId());
            weekPlanPO.setWeekId(weekTimeId);
            weekPlanPO.setInsertTime(LocalDateTime.now());
        }
        saveBatch(BeanUtil.listA2ListB(weekPlanPOList,SysWeekPlan.class));
        return new ApiResponse<>();
    }


    @Override
    public ApiResponse<Void> weekPlanUpdate (WeekPlanUpdatePO weekPlanUpdatePO){
        Long userId = weekPlanUpdatePO.getUserId();
        Long weekTimeId = weekPlanUpdatePO.getWeekId();
        //先找到本周的weekId
        LocalDateTime now = LocalDateTime.now();
        SysWeekTime sysWeekTimeServiceOne = sysWeekTimeService.getById(weekTimeId);
//        if (sysWeekTimeServiceOne.getBeginTime().isBefore(now.plusDays(6L))
        if (sysWeekTimeServiceOne.getBeginTime().isBefore(now)
        ) {
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "历史记录已经存档，不能进行修改");
        }

        List<WeekPlanUpdateSinglePO> weekPlanPOList = weekPlanUpdatePO.getWeekPlanPOList();
        if (weekPlanPOList.isEmpty()) {
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周计划不能为空");
        }
        if (weekPlanPOList.size() > 20) {
            throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周计划长度最大为20");
        }
        for (WeekPlanUpdateSinglePO weekPlanPO : weekPlanPOList) {
            if (weekPlanPO.getWeekDay() == null) {
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "所有周计划的时间都不能为空");
            }
            if(weekPlanPO.getTaskDifficulty()==null){
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "所有周计划的任务难度都不能为空");
            }
            weekPlanPO.setUserId(userId);
            weekPlanPO.setWeekId(weekTimeId);
            weekPlanPO.setInsertTime(LocalDateTime.now());
        }

        remove(new LambdaQueryWrapper<SysWeekPlan>().
                eq(SysWeekPlan::getWeekId,weekTimeId)
                .eq(SysWeekPlan::getUserId,userId)
        );
        saveBatch(BeanUtil.listA2ListB(weekPlanPOList, SysWeekPlan.class));
        return new ApiResponse<>();
    }

    @Override
    public ApiResponse<Void> weekPlanDelete (WeekPlanPO weekPlanPO){
        Long userId = weekPlanPO.getUserId();
        Long weekTimeId = weekPlanPO.getWeekId();
        System.out.println(userId+""+weekTimeId);
        remove(new LambdaQueryWrapper<SysWeekPlan>()
                .eq(SysWeekPlan::getWeekId,weekTimeId)
                .eq(SysWeekPlan::getUserId,userId)
        );
        return new ApiResponse<>();
    }


    @Override
    public ApiResponse<WeekPlanInfoVO> weekPlanGetById (WeekPlanPO weekPlanPO){
        Long userId = weekPlanPO.getUserId();
        Long weekTimeId = weekPlanPO.getWeekId();
        SysWeekTime byId1 = sysWeekTimeService.getById(weekTimeId);
        Page<SysWeekPlan> page = new Page<>(weekPlanPO.getPageNumber(), weekPlanPO.getPageSize());
        Page<SysWeekPlan> sysWeekPlanPage = page(page, new LambdaQueryWrapper<SysWeekPlan>()
                .eq(SysWeekPlan::getUserId,userId)
                .eq(SysWeekPlan::getWeekId, weekTimeId)
                .orderByDesc(SysWeekPlan::getInsertTime)
        );
        List<SysWeekPlan> list = sysWeekPlanPage.getRecords();
        WeekPlanInfoVO weekPlanInfoVO = new WeekPlanInfoVO();
        List<WeekPlanInfoVO> weekPlanInfoVOS = BeanUtil.listA2ListB(list, WeekPlanInfoVO.class);
        for (WeekPlanInfoVO planInfoVO : weekPlanInfoVOS) {
            planInfoVO.setNowTime(byId1.getBeginTime().plusDays((planInfoVO.getWeekDay()-1)));
        }
        weekPlanInfoVO.setWeekPlanInfoVOList(weekPlanInfoVOS);
        weekPlanInfoVO.setBeginTime(byId1.getBeginTime());
        weekPlanInfoVO.setEndTime(byId1.getEndTime());
        return new ApiResponse<WeekPlanInfoVO>(Collections.singleton(weekPlanInfoVO), sysWeekPlanPage.getTotal());

    }

    @Override
    public ApiResponse<WeekPlanInfoVO> weekPlanGetByIdNoPaging (WeekPlanPO weekPlanPO){
        Long userId = weekPlanPO.getUserId();
        Long weekTimeId = weekPlanPO.getWeekId();
        SysWeekTime byId1 = sysWeekTimeService.getById(weekTimeId);
        List<SysWeekPlan> list = list(new LambdaQueryWrapper<SysWeekPlan>()
                .eq(SysWeekPlan::getUserId, userId)
                .eq(SysWeekPlan::getWeekId, weekTimeId)
                .orderByDesc(SysWeekPlan::getInsertTime)
        );
        WeekPlanInfoVO weekPlanInfoVO = new WeekPlanInfoVO();
        weekPlanInfoVO.setWeekPlanInfoVOList(BeanUtil.listA2ListB(list, WeekPlanInfoVO.class));
        weekPlanInfoVO.setBeginTime(byId1.getBeginTime());
        weekPlanInfoVO.setEndTime(byId1.getEndTime());
        return new ApiResponse<WeekPlanInfoVO>(Collections.singleton(weekPlanInfoVO));
    }

    public static void main(String[] args) {
        System.out.println(LocalDateTime.now().plusDays(6L));
    }

}









